<?php
/**
 * 功能描述：用来处理文件的一些方法
 */
class File{
    /**
     * 在给定的路径下面根据时间生成唯一的文件名称
     * @param $pPath 路径
     * @param $pFileType 文件类型
     * @return 返回文件名称
     */
    function getFileNameByTime($pPath, $pFileType){
        //如果没有在后面加上路径分隔符，则加上
        $pPath = StringTools::getValidPath($pPath);

        do
        {
            $fileName = StringTools::getDateTime(14);
            list($usec, $sec) = explode(" ",microtime());
            $fileName .= StringTools::right((int)($usec*1000000)+10000000, 6);
        }while(file_exists($pPath.$fileName.".".$pFileType));
        return $fileName.".".$pFileType;
    }


    /**
     * 获取文件扩展名
     * @param $pFileName 文件名称
     * @return 返回文件扩展名
     */
    function getExtend($pFileName){
        $pos = strpos($pFileName,'?');
        if($pos){
        	$pFileName=substr($pFileName,0,$pos);
        }
	    //echo $pFileName;
        $arr = explode("/", $pFileName);
        $name = array_pop($arr);

        $ext = explode(".", $name);
        return (count($ext)==1) ? "" : array_pop($ext);
    }

    /**
     * 将数据写到文件
     * @param $pFileName 文件名称
     * @param $pContent 数据
     * @return 返回文件扩展名
     */
    public static function writeFile($pFilename, $pContent, $pWay="w"){
        // 首先我们要确定文件存在并且可写。
        if (!file_exists($pFilename) || is_writable($pFilename)){
            if (!$handle = fopen($pFilename, $pWay)){
                return false;
            }
            flock($handle, LOCK_EX);
            // 将$pContent写入到我们打开的文件中。
            if (!fwrite($handle, $pContent)){
                return false;
            }
            flock($handle, LOCK_UN); // 释放锁定
            fclose($handle);
            chmod ($pFilename, 0777);
            return true;
        }else{
            return false;
        }
    }


    /**
     * 读取文件的内容并返回，如果文件不存在返回空字符串
     * @param $pFileName 文件名称
     * @return 返回文件内容，如果文件不存在返回空字符串
     */
    public static function readFile($pFileName, $pReportError=true)
    {
        if($pReportError==true)
            return file_get_contents($pFileName);
        else
        {
            if(self::checkFile($pFileName))
            {
                return file_get_contents($pFileName);
            }
            else
            {
                return "";
            }
        }
    }

    public static function checkFile($pFileName){
        $handle = fopen($pFileName, "r");
        if($handle==false)
            return false;
        else
        {
            fclose($handle);
            return true;
        }
    }





    public static function backupFile($pFileName,$suffix = null)
    {
        !isset($suffix) && $time = StringTools::getDateTime(14);
        if(file_exists($pFileName))
            copy($pFileName, $pFileName.$time);
    }

    public static function pathinfo($pFileName, $pSplitChar="/")
    {

        $arr = explode($pSplitChar, $pFileName);
        $name = array_pop($arr);

        $return = array();
        $return["dirname"] = implode($pSplitChar, $arr);
        $return["basename"] = $name;

        $arr = explode(".", $name);
        if(count($arr)>1)
        {
            $return["extension"] = array_pop($arr);
            $return["simname"] = implode(".", $arr);;
        }
        else
        {
            $return["extension"] = "";
            $return["simname"] = $name;
        }

        return $return;
    }

    public static function getNextName($pFileName, $pLength = 1){
        $pathinfo = self::pathinfo($pFileName);
        $name = $pathinfo["simname"];
        if(preg_match("/(.*)--\[N([0-9]+)\]/msi", $name, $matches))
        {
            $name = $matches[1];
            $no = $matches[2]+1;
        }
        else
        {
            $no = 1;
        }
        $no = StringTools::right("0000000000000000000{$no}", max($pLength, strlen($no)));
        return "{$pathinfo["dirname"]}/{$name}--[N{$no}].{$pathinfo["extension"]}";
    }

    public static function valid($pFileName, $pReplaceChar="-"){
        return ereg_replace("[\\\/\*\?\"<>|:]", $pReplaceChar, $pFileName);
    }
    
    public static function readCSV($pFileName, $pLength=4096, $pDelimiter=',', $pEnclosure='"'){
        $result = array();
        $handle = fopen ($pFileName,"r");
        while ($data = fgetcsv($handle, $pLength, $pDelimiter, $pEnclosure))
        {
            $result[] = $data;
        }
        fclose ($handle);
        return $result;
    }

    /**
     * 保存或者将让浏览器保存csv文件的方法
     * @param $pSource 数据来源，根据pFlag的值分别为数组，字符串，文件名
     * @param $pFlag 数据来源类别，可选内容array,string,file
     * @param $pFileName 文件名，如果是让浏览器下载则为默认的保存的文件名称，如果是保存文件则为文件名称
     * @param $pSaveFlag 是否保存文件
     * @return 返回输入路径下的所有目录列表
     */
    public static function headerCSV($pSource, $pFlag, $pFileName='save.csv', $pSaveFlag=false)
    {
        $file_content = "";
        switch(strtolower(trim($pFlag)))
        {
            case "string":
                $file_content = $pSource;
                break;
            case "array":
                foreach($pSource as $row)
                {
                    if(is_array($row))
                    {
                        $temp = array();
                        foreach($row as $list)
                        {
                            $str = str_replace('"', '""', $list);
                            $temp[] = (strrpos($str, '"') || strrpos($str, ',')) ? "\"{$str}\"" : $str;
                        }
                        $file_content .= implode(',', $temp)."\r\n";
                    }
                    else
                    {
                        $file_content .= $row."\r\n";
                    }
                }
                break;
            case "file":
                $file_content = self::readFile($pSource);
                break;
            default:
                echo "Error : 数据来源标志错误！";
        }

        if($pSaveFlag)
        {
            self::writeFile($pFileName, $file_content);
        }
        else
        {

            header( "Content-Type: text/csv" );
            header( "Content-Length: ".strlen( $file_content ));
            header( "Expires: Mon, 26 Jul 1997 05:00:00 GMT" );
            header( "Last-Modified: ". gmdate("D, d M Y H:i:s") ." GMT" );
            //header( "Cache-Control: no-store,no-cache,must-revalidate,post-check=0,pre-check=0,max-age=0,private",false );
            header( "Pragma: no-cache" );
            header( "Content-Disposition: attachment; filename={$pFileName}" );
            echo $file_content;
            exit;
        }
    }

    public static function copy($pSource, $pTarget){
        copy($pSource, $pTarget);
        touch($pTarget, filemtime($pSource));
    }

 

   public static function parseSelectXml($pFileName, $pFlag=0)
    {
        $xml = simplexml_load_file($pFileName);
        //print_r($xml);

        $result = array();
        foreach ($xml->xpath('//option') as $option)
        {
            $value = iconv("UTF-8", "GB18030", $option->value);
            $title = iconv("UTF-8", "GB18030", $option->title);
            if($pFlag==0)
                $result[$value] = $title;
            else
                $result[$title] = $value;
        }
        return $result;
    }

   public static function headerFile($pFileName, $pFileTitle="")
    {
        if(!is_readable($pFileName))
        {
            echo "Error:文件不存在或不可读!";
            exit;
        }

        $fileTypeArray = array (
    		'cdf' => 'application/x-cdf',
    		'fif' => 'application/fractals',
    		'spl' => 'application/futuresplash',
    		'hta' => 'application/hta',
    		'hqx' => 'application/mac-binhex40',
    		'doc' => 'application/msword',
    		'pdf' => 'application/pdf',
    		'p10' => 'application/pkcs10',
    		'p7m' => 'application/pkcs7-mime',
    		'p7s' => 'application/pkcs7-signature',
    		'cer' => 'application/x-x509-ca-cert',
    		'crl' => 'application/pkix-crl',
    		'ps' => 'application/postscript',
    		'setpay' => 'application/set-payment-initiation',
    		'setreg' => 'application/set-registration-initiation',
    		'smi' => 'application/smil',
    		'edn' => 'application/vnd.adobe.edn',
    		'pdx' => 'application/vnd.adobe.pdx',
    		'rmf' => 'application/vnd.adobe.rmf',
    		'xdp' => 'application/vnd.adobe.xdp+xml',
    		'xfd' => 'application/vnd.adobe.xfd+xml',
    		'xfdf' => 'application/vnd.adobe.xfdf',
    		'fdf' => 'application/vnd.fdf',
    		'xls' => 'application/x-msexcel',
    		'sst' => 'application/vnd.ms-pki.certstore',
    		'pko' => 'application/vnd.ms-pki.pko',
    		'cat' => 'application/vnd.ms-pki.seccat',
    		'stl' => 'application/vnd.ms-pki.stl',
    		'ppt' => 'application/x-mspowerpoint',
    		'wpl' => 'application/vnd.ms-wpl',
    		'rms' => 'video/vnd.rn-realvideo-secure',
    		'rm' => 'application/vnd.rn-realmedia',
    		'rmvb' => 'application/vnd.rn-realmedia-vbr',
    		'rnx' => 'application/vnd.rn-realplayer',
    		'rjs' => 'application/vnd.rn-realsystem-rjs',
    		'rjt' => 'application/vnd.rn-realsystem-rjt',
    		'rmj' => 'application/vnd.rn-realsystem-rmj',
    		'rmx' => 'application/vnd.rn-realsystem-rmx',
    		'rmp' => 'application/vnd.rn-rn_music_package',
    		'rsml' => 'application/vnd.rn-rsml',
    		'z' => 'application/x-compress',
    		'tgz' => 'application/x-compressed',
    		'etd' => 'application/x-ebx',
    		'gz' => 'application/x-gzip',
    		'ins' => 'application/x-internet-signup',
    		'iii' => 'application/x-iphone',
    		'jnlp' => 'application/x-java-jnlp-file',
    		'latex' => 'application/x-latex',
    		'nix' => 'application/x-mix-transfer',
    		'mxp' => 'application/x-mmxp',
    		'asx' => 'video/x-ms-asf-plugin',
    		'wmd' => 'application/x-ms-wmd',
    		'wmz' => 'application/x-ms-wmz',
    		'p12' => 'application/x-pkcs12',
    		'p7b' => 'application/x-pkcs7-certificates',
    		'p7r' => 'application/x-pkcs7-certreqresp',
    		'swf' => 'application/x-shockwave-flash',
    		'sit' => 'application/x-stuffit',
    		'tar' => 'application/x-tar',
    		'man' => 'application/x-troff-man',
    		'zip' => 'application/x-zip-compressed',
    		'xml' => 'text/xml',
    		'3gp' => 'video/3gpp-encrypted',
    		'3g2' => 'video/3gpp2',
    		'aiff' => 'audio/x-aiff',
    		'au' => 'audio/basic',
    		'mid' => 'midi/mid',
    		'mp3' => 'audio/x-mpg',
    		'm3u' => 'audio/x-mpegurl',
    		'ra' => 'audio/x-realaudio',
    		'wav' => 'audio/x-wav',
    		'wax' => 'audio/x-ms-wax',
    		'wma' => 'audio/x-ms-wma',
    		'ram' => 'audio/x-pn-realaudio',
    		'bmp' => 'image/bmp',
    		'gif' => 'image/gif',
    		'jpg' => 'image/pjpeg',
    		'png' => 'image/x-png',
    		'tiff' => 'image/tiff',
    		'rp' => 'image/vnd.rn-realpix',
    		'ico' => 'image/x-icon',
    		'xbm' => 'image/xbm',
    		'css' => 'text/css',
    		'323' => 'text/h323',
    		'htm' => 'text/html',
    		'uls' => 'text/iuls',
    		'txt' => 'text/plain',
    		'wsc' => 'text/scriptlet',
    		'rt' => 'text/vnd.rn-realtext',
    		'htt' => 'text/webviewhtml',
    		'htc' => 'text/x-component',
    		'iqy' => 'text/x-ms-iqy',
    		'odc' => 'text/x-ms-odc',
    		'rqy' => 'text/x-ms-rqy',
    		'vcf' => 'text/x-vcard',
    		'avi' => 'video/x-msvideo',
    		'mpeg' => 'video/x-mpeg2a',
    		'rv' => 'video/vnd.rn-realvideo',
    		'wm' => 'video/x-ms-wm',
    		'wmv' => 'video/x-ms-wmv',
    		'wmx' => 'video/x-ms-wmx',
    		'wvx' => 'video/x-ms-wvx');

		$extence = strtolower(self::getExtend($pFileName));
		if(array_key_exists($extence,$fileTypeArray))
		{
			$type = $fileTypeArray[$extence];
		}
		else
		{
			$type = "application/force-download";
		}
		$name = $pFileTitle=="" ? basename($pFileName) : $pFileTitle;

	 	header("Content-type: {$type}");
		header("Content-Disposition: attachment; filename={$name}");
		header("Expires: 0");
		header("Cache-Control: must-revalidate, post-check=0,pre-check=0");
		header("Pragma: public");

        $file_content = file_get_contents($pFileName);
        echo $file_content;
        exit;
    }

    public static function headerString($pString, $pExtentend, $pName = "")
    {
    	$fileTypeArray = array (
    		'cdf' => 'application/x-cdf',
    		'fif' => 'application/fractals',
    		'spl' => 'application/futuresplash',
    		'hta' => 'application/hta',
    		'hqx' => 'application/mac-binhex40',
    		'doc' => 'application/msword',
    		'pdf' => 'application/pdf',
    		'p10' => 'application/pkcs10',
    		'p7m' => 'application/pkcs7-mime',
    		'p7s' => 'application/pkcs7-signature',
    		'cer' => 'application/x-x509-ca-cert',
    		'crl' => 'application/pkix-crl',
    		'ps' => 'application/postscript',
    		'setpay' => 'application/set-payment-initiation',
    		'setreg' => 'application/set-registration-initiation',
    		'smi' => 'application/smil',
    		'edn' => 'application/vnd.adobe.edn',
    		'pdx' => 'application/vnd.adobe.pdx',
    		'rmf' => 'application/vnd.adobe.rmf',
    		'xdp' => 'application/vnd.adobe.xdp+xml',
    		'xfd' => 'application/vnd.adobe.xfd+xml',
    		'xfdf' => 'application/vnd.adobe.xfdf',
    		'fdf' => 'application/vnd.fdf',
    		'xls' => 'application/x-msexcel',
    		'sst' => 'application/vnd.ms-pki.certstore',
    		'pko' => 'application/vnd.ms-pki.pko',
    		'cat' => 'application/vnd.ms-pki.seccat',
    		'stl' => 'application/vnd.ms-pki.stl',
    		'ppt' => 'application/x-mspowerpoint',
    		'wpl' => 'application/vnd.ms-wpl',
    		'rms' => 'video/vnd.rn-realvideo-secure',
    		'rm' => 'application/vnd.rn-realmedia',
    		'rmvb' => 'application/vnd.rn-realmedia-vbr',
    		'rnx' => 'application/vnd.rn-realplayer',
    		'rjs' => 'application/vnd.rn-realsystem-rjs',
    		'rjt' => 'application/vnd.rn-realsystem-rjt',
    		'rmj' => 'application/vnd.rn-realsystem-rmj',
    		'rmx' => 'application/vnd.rn-realsystem-rmx',
    		'rmp' => 'application/vnd.rn-rn_music_package',
    		'rsml' => 'application/vnd.rn-rsml',
    		'z' => 'application/x-compress',
    		'tgz' => 'application/x-compressed',
    		'etd' => 'application/x-ebx',
    		'gz' => 'application/x-gzip',
    		'ins' => 'application/x-internet-signup',
    		'iii' => 'application/x-iphone',
    		'jnlp' => 'application/x-java-jnlp-file',
    		'latex' => 'application/x-latex',
    		'nix' => 'application/x-mix-transfer',
    		'mxp' => 'application/x-mmxp',
    		'asx' => 'video/x-ms-asf-plugin',
    		'wmd' => 'application/x-ms-wmd',
    		'wmz' => 'application/x-ms-wmz',
    		'p12' => 'application/x-pkcs12',
    		'p7b' => 'application/x-pkcs7-certificates',
    		'p7r' => 'application/x-pkcs7-certreqresp',
    		'swf' => 'application/x-shockwave-flash',
    		'sit' => 'application/x-stuffit',
    		'tar' => 'application/x-tar',
    		'man' => 'application/x-troff-man',
    		'zip' => 'application/x-zip-compressed',
    		'xml' => 'text/xml',
    		'3gp' => 'video/3gpp-encrypted',
    		'3g2' => 'video/3gpp2',
    		'aiff' => 'audio/x-aiff',
    		'au' => 'audio/basic',
    		'mid' => 'midi/mid',
    		'mp3' => 'audio/x-mpg',
    		'm3u' => 'audio/x-mpegurl',
    		'ra' => 'audio/x-realaudio',
    		'wav' => 'audio/x-wav',
    		'wax' => 'audio/x-ms-wax',
    		'wma' => 'audio/x-ms-wma',
    		'ram' => 'audio/x-pn-realaudio',
    		'bmp' => 'image/bmp',
    		'gif' => 'image/gif',
    		'jpg' => 'image/pjpeg',
    		'png' => 'image/x-png',
    		'tiff' => 'image/tiff',
    		'rp' => 'image/vnd.rn-realpix',
    		'ico' => 'image/x-icon',
    		'xbm' => 'image/xbm',
    		'css' => 'text/css',
    		'323' => 'text/h323',
    		'htm' => 'text/html',
    		'uls' => 'text/iuls',
    		'txt' => 'text/plain',
    		'wsc' => 'text/scriptlet',
    		'rt' => 'text/vnd.rn-realtext',
    		'htt' => 'text/webviewhtml',
    		'htc' => 'text/x-component',
    		'iqy' => 'text/x-ms-iqy',
    		'odc' => 'text/x-ms-odc',
    		'rqy' => 'text/x-ms-rqy',
    		'vcf' => 'text/x-vcard',
    		'avi' => 'video/x-msvideo',
    		'mpeg' => 'video/x-mpeg2a',
    		'rv' => 'video/vnd.rn-realvideo',
    		'wm' => 'video/x-ms-wm',
    		'wmv' => 'video/x-ms-wmv',
    		'wmx' => 'video/x-ms-wmx',
    		'wvx' => 'video/x-ms-wvx');
		$extence = strtolower($pExtentend);
		if(array_key_exists($extence,$fileTypeArray))
		{
			$type = $fileTypeArray[$extence];
		}
		else
		{
			$type = "application/force-download";
		}
		$name = $pName=="" ? 'attach_'.date("Ymdhis",time()).'.'.$extence : $pName.'.'.$extence;

	 	header("Content-type: {$type}");
		header("Content-Disposition: attachment; filename={$name}");
		header("Expires: 0");
		header("Cache-Control: must-revalidate, post-check=0,pre-check=0");
		header("Pragma: public");

        $file_content = $pString;
        echo $file_content;
        exit;
    }

    public static function xml2Js($pJsFile, $pXmlFile, $pTagName){
        $data = self::parseSelectXml($pXmlFile);

        self::updateJs($data, $pJsFile, $pTagName);
    }

    public static function updateJs($pDataSource, $pJsFile, $pTagName){
        //解析Xml文件，并得到相应的JS Code
        $tag = "//----{$pTagName}----//";
        $tmp = array($tag);
        $tmp[] = "{$pTagName} = new Array();";
        $tmp[] = "index = 0;";
        foreach($pDataSource as $key => $value)
        {
            $tmp[] = "{$pTagName}[index++] = new Array(\"{$key}\", \"".str_replace('"', '\"', StringTools::htmlspecialchars_decode($value))."\");";
        }
        $tmp[] = $tag;
        $js_content =  implode("\r\n", $tmp);

        //替换原有的JS Code 或者新增JS Code
        $file_content = "";
        if(file_exists($pJsFile))
        {
            $file_string = file_get_contents($pJsFile);
            $file_array = explode($tag, $file_string);
            if(count($file_array)==3)
            {
                //已经存在，更新
                $file_array[1] = $js_content;
            }
            else
            {
                //不存在 追加
                $file_array[] = "\r\n\r\n";
                $file_array[] = $js_content;
            }
            $file_content = implode("", $file_array);
        }
        else
        {
            $file_content = $js_content;
        }
        file_put_contents($pJsFile, $file_content);
    }

    public static function createXml($pFileName, $pDataArray){
        //echo $pFileName;
        //htmlspecialchars db64_encode
        $str = '<?xml version="1.0" encoding="UTF-8"?>';
        $str .= "\n<options>\n";
        foreach($pDataArray as $Option)
        {
            $str .= "\t<option>\n";
            $str .= "\t\t<title>".iconv("GB18030", "UTF-8", htmlspecialchars($Option['title']))."</title>\n";
            $str .= "\t\t<value>".iconv("GB18030", "UTF-8", htmlspecialchars($Option['value']))."</value>\n";
            $Option['parent'] = isset($Option['parent']) ? $Option['parent'] : "";
            $str .= "\t\t<parent>{$Option['parent']}</parent>\n";
            $str .= "\t</option>\n";
        }
        $str .= "</options>\n";
        file_put_contents($pFileName, $str);
    }

    public static function xml2php($pJsFile, $pXmlFile, $pTagName){
        //解析Xml文件，并得到相应的JS Code
        $tag = "//----{$pTagName}----//";
        $data = self::parseSelectXml($pXmlFile);
        $tmp = array($tag);
        $tmp[] = "\$this->mData['{$pTagName}'] = array();";
        foreach($data as $key => $value)
        {
            $tmp[] = "\$this->mData['{$pTagName}']['{$key}'] = '{$value}';";
        }
        $tmp[] = $tag;
        $js_content =  implode("\r\n", $tmp);

        //替换原有的JS Code 或者新增JS Code
        $file_content = "";
        if(file_exists($pJsFile)){
            $file_string = file_get_contents($pJsFile);
            $class_array = explode("//<--construct-->", $file_string);
            if(count($class_array)!=3)
            {
                throw new Exception("文件结构错误！");
            }

            $file_array = explode($tag, $class_array[1]);
            if(count($file_array)==3)
            {
                //已经存在，更新
                $file_array[1] = $js_content;
            }
            else
            {
                //不存在 追加
                $file_array[] = "\r\n\r\n";
                $file_array[] = $js_content;
            }
            $class_array[1] = implode("", $file_array);
            $file_content = implode("//<--construct-->", $class_array);
        }else{
            throw new Exception("class.StaticData.php文件不存在！");
        }
        file_put_contents($pJsFile, $file_content);
    }

    public static function getVailidName($pString, $pReplaceChar=" "){
        return preg_replace("#[<>:|/\"\\\*\?]#msi", $pReplaceChar, $pString);
    }
}
